import 'dart:async';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'package:dio/dio.dart';
import 'exceptions.dart';
import 'failures.dart';
import '../../app/shared/widgets/dialogs/error_dialog.dart';

/// 全局错误处理器
class ErrorHandler {
  /// 私有构造函数
  ErrorHandler._();
  
  /// 全局实例
  static final instance = ErrorHandler._();

  /// 处理异常，转换为统一的ApiException
  ApiException handleException(dynamic error) {
    if (kDebugMode) {
      print('ErrorHandler处理异常: $error');
    }
    
    // 已经是ApiException，直接返回
    if (error is ApiException) {
      return error;
    }
    
    // 处理不同类型的异常
    if (error is SocketException || error is WebSocketException) {
      return NetworkException(message: '网络连接失败: ${error.message}');
    }
    
    if (error is TimeoutException || error is DioExceptionType) {
      if (error.toString().contains('connectTimeout') || 
          (error is DioExceptionType && error == DioExceptionType.connectionTimeout)) {
        return TimeoutException(message: '连接超时，请检查网络');
      }
      
      if (error.toString().contains('receiveTimeout') || 
          (error is DioExceptionType && error == DioExceptionType.receiveTimeout)) {
        return TimeoutException(message: '接收数据超时，请稍后再试');
      }
      
      if (error.toString().contains('sendTimeout') || 
          (error is DioExceptionType && error == DioExceptionType.sendTimeout)) {
        return TimeoutException(message: '发送数据超时，请稍后再试');
      }
      
      return TimeoutException();
    }
    
    if (error is FormatException) {
      return ParseException(message: '数据格式错误: ${error.message}');
    }
    
    if (error is DioException) {
      // 处理DIO异常
      return _handleDioError(error);
    }
    
    if (error is HttpException) {
      return ServerException(message: '服务器错误: ${error.message}');
    }
    
    // 处理异常堆栈信息，便于调试
    if (error is Error) {
      return UndefinedException(
        message: '程序错误: ${error.toString()}',
        code: 'ERROR',
      );
    }
    
    // 未知异常
    return UndefinedException(
      message: '未知错误: ${error.toString()}',
    );
  }
  
  /// 处理DIO异常
  ApiException _handleDioError(DioException error) {
    switch (error.type) {
      case DioExceptionType.connectionTimeout:
      case DioExceptionType.sendTimeout:
      case DioExceptionType.receiveTimeout:
        return TimeoutException(message: '请求超时，请检查网络连接');
      
      case DioExceptionType.badResponse:
        // 处理HTTP状态码错误
        return _handleResponseError(error.response);
      
      case DioExceptionType.cancel:
        return CancelException();
      
      case DioExceptionType.badCertificate:
        return ServerException(
          message: '服务器证书验证失败',
          statusCode: 0,
          code: 'BAD_CERTIFICATE',
        );
      
      case DioExceptionType.connectionError:
        return NetworkException(
          message: '网络连接错误: ${error.message}',
        );
      
      case DioExceptionType.unknown:
      default:
        if (error.error is SocketException) {
          return NetworkException(
            message: '网络异常，无法连接到服务器',
          );
        }
        
        return UndefinedException(
          message: '未知的请求错误: ${error.message}',
        );
    }
  }
  
  /// 处理HTTP响应错误
  ApiException _handleResponseError(Response? response) {
    if (response == null) {
      return ServerException(
        message: '未收到服务器响应',
      );
    }
    
    final statusCode = response.statusCode ?? 0;
    String message = '';
    
    try {
      // 尝试从响应中获取错误信息
      if (response.data is Map) {
        final data = response.data as Map;
        message = data['message'] as String? ?? 
                 data['error'] as String? ?? 
                 '请求失败($statusCode)';
      } else if (response.data is String && (response.data as String).isNotEmpty) {
        message = response.data as String;
      } else {
        message = _getDefaultErrorMessage(statusCode);
      }
    } catch (e) {
      message = _getDefaultErrorMessage(statusCode);
    }
    
    // 根据状态码创建对应的异常
    switch (statusCode) {
      case 400:
        return BadRequestException(
          message: message,
          statusCode: statusCode,
        );
      
      case 401:
        return UnauthorizedException(
          message: message,
          statusCode: statusCode,
        );
      
      case 403:
        return ForbiddenException(
          message: message,
          statusCode: statusCode,
        );
      
      case 404:
        return NotFoundException(
          message: message,
          statusCode: statusCode,
        );
      
      case 408:
        return TimeoutException(
          message: message,
          statusCode: statusCode,
        );
      
      case 500:
      case 501:
      case 502:
      case 503:
      case 504:
      case 505:
        return ServerException(
          message: message,
          statusCode: statusCode,
        );
      
      default:
        return ApiException(
          message: message,
          statusCode: statusCode,
        );
    }
  }
  
  /// 获取默认错误消息
  String _getDefaultErrorMessage(int statusCode) {
    switch (statusCode) {
      case 400:
        return '请求参数错误';
      case 401:
        return '未授权，请重新登录';
      case 403:
        return '拒绝访问';
      case 404:
        return '请求的资源不存在';
      case 408:
        return '请求超时';
      case 500:
        return '服务器内部错误';
      case 501:
        return '服务未实现';
      case 502:
        return '网关错误';
      case 503:
        return '服务不可用';
      case 504:
        return '网关超时';
      case 505:
        return 'HTTP版本不受支持';
      default:
        return '请求失败($statusCode)';
    }
  }
  
  /// 显示错误消息
  void showError(dynamic error) {
    final exception = handleException(error);
    
    Get.snackbar(
      '错误',
      exception.message,
      snackPosition: SnackPosition.BOTTOM,
    );
  }

  /// 处理错误
  void handleError(dynamic error, [StackTrace? stackTrace]) {
    // 记录错误信息
    _logError(error, stackTrace);
    
    // 转换错误为Failure
    final failure = _mapErrorToFailure(error);
    
    // 显示错误对话框
    _showErrorDialog(failure);
  }

  /// 记录错误信息
  void _logError(dynamic error, [StackTrace? stackTrace]) {
    debugPrint('ERROR: $error');
    if (stackTrace != null) {
      debugPrint('STACK TRACE: $stackTrace');
    }
    
    // 在生产环境中可以发送错误报告到服务器
    if (!kDebugMode) {
      // TODO: 发送错误报告到服务器
    }
  }

  /// 将错误转换为Failure
  Failure _mapErrorToFailure(dynamic error) {
    if (error is Failure) {
      return error;
    } else if (error is ServerException) {
      return ServerFailure(error.message);
    } else if (error is CacheException) {
      return CacheFailure(error.message);
    } else if (error is NetworkException) {
      return NetworkFailure(error.message);
    } else if (error is UnauthorizedException) {
      return UnauthorizedFailure(error.message);
    } else if (error is TimeoutException) {
      return NetworkFailure('请求超时，请稍后重试');
    } else if (error is FormatException) {
      return ValidationFailure('数据格式错误');
    } else if (error is ValueException) {
      return ValidationFailure(error.message);
    } else if (error is DatabaseException) {
      return DatabaseFailure(error.message);
    } else if (error is AuthException) {
      return AuthenticationFailure(error.message);
    } else if (error is PermissionException) {
      return PermissionFailure(error.message);
    } else {
      return UnexpectedFailure(error.toString());
    }
  }

  /// 显示错误对话框
  void _showErrorDialog(Failure failure) {
    // 在主线程中显示错误对话框
    Get.showDialog(
      barrierDismissible: true,
      builder: (_) => ErrorDialog(message: failure.message),
    );
  }
} 